home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
pcpilot.arc
/
SCR.ARC
/
SCR.C
< prev
next >
Wrap
Text File
|
1990-01-14
|
15KB
|
537 lines
/* ------------------------------------------------------------------------ */
/* SCR.C */
/* See pg. 162 of Systems Programming in Turbo C */
/* */
/* ------------------------------------------------------------------------ */
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <mem.h>
#include <ctype.h>
#include "kbd.h"
#include "scr.h"
void ScrGetMode (struct Mode *ModePtr)
/*
This function gets the current video mode, number of display columns,
and video page
*/
{
unsigned char AhHold;
_AH = 15; /* BIOS get video mode service */
geninterrupt (0x10); /* BIOS video service */
AhHold = _AH; /* AH returns columns */
ModePtr->VideoMode = _AL; /* AL returns mode */
ModePtr->Columns = AhHold;
ModePtr->VideoPage = _BH; /* BH returns active page */
}
void ScrSetMode (struct Mode *ModePtr)
/*
This function sets the video mode and display page
*/
{
_AH = 0; /* BIOS set mode service */
_AL = ModePtr->VideoMode; /* BIOS video service */
geninterrupt (0x10); /* INT 10H
_AH = 5; /* BIOS set active page service */
_AL = ModePtr->VideoPage;
geninterrupt (0x10);
}
void InitScr(void)
{
if (*(char far *)0x00400049 == 7) {
VideoSeg = 0xb000;
VideoMode = MONO;
}
}
void ScrGetCur (int *Col, int *Row, int Page)
/*
This function assigns the current cursor position
*/
{
_BH = (unsigned char)Page;
_AH = 3; /* BIOS get cursor position */
geninterrupt (0x10);
*Row = _DH;
*Col = _DL;
}
void ScrSetCur (int Col, int Row, int Page)
/*
This function the cursor position
*/
{
_BH = (unsigned char)Page;
_DH = Row;
_DL = Col;
_AH = 2; /* BIOS set cursor position */
geninterrupt (0x10);
}
void ScrGetStyle (int *StartLine, int *StopLine)
/*
This function determines the current cursor's shape
*/
{
_BH = 0; /* Get it for page 0, since all pages have same style */
_AH = 3; /* BIOS read cursor position */
geninterrupt (0x10);
*StartLine = _CH;
*StopLine = _CL;
}
void ScrSetStyle (int StartLine, int StopLine)
/*
This function sets the cursor shape
*/
{
_CH = StartLine;
_CL = StopLine;
_AH = 1; /* BIOS set cursor type */
geninterrupt (0x10);
}
int GetKey(void)
{
return (KbdGetC()&0x00ff);
}
/* --------------------------- ScrPush/ScrPop ----------------------------- */
#define MAXSCREENS 10
static char *BufPtar [MAXSCREENS]; /* Elements of this array point to */
/* the screen storage buffers on the */
/* scree stack. */
static int BufIdx = -1; /* Index to BufPtar */
int ScrPush (void)
/*
This fuction saves the contents of the current scree on the screen
stack.
*/
{
int Vseg;
if (++BufIdx >= MAXSCREENS) /* Test if maximum stack size exceeded */
return (MAXTOOSMALL);
/* Allocate heap memory for one screen */
if ((BufPtar [BufIdx] = malloc (4000)) == NULL) {
--BufIdx; /* Out of heap memory */
return (NOHEAP);
}
if (*(char far *)0x00400049 == 7) /* Test video mode */
Vseg = 0xb000; /* Monochrome video memory */
else
Vseg = 0xb800; /* Color video memory */
/* Transfer video memory */
movedata (Vseg,0,FP_SEG ((char far *)BufPtar [BufIdx]),
FP_OFF ((char far *)BufPtar [BufIdx]),4000);
return (NOERROR);
}
int ScrPop (int Remove)
/*
This function restores the most recently saved screen on the screen
stack, and removes the screen from the stack IF 'Remove' is nonzero.
*/
{
int Vseg;
if (BufIdx < 0) /* No screens to restore */
return (STACKEMPTY);
if (*(char far *)0x00400049 == 7) /* Test video mode */
Vseg = 0xb000;
else
Vseg = 0xb800;
/* Transfer video memory */
movedata (FP_SEG ((char far *)BufPtar [BufIdx]),
FP_OFF ((char far *)BufPtar [BufIdx]), Vseg, 0, 4000);
if (Remove) /* Remove screen from stack */
free (BufPtar [BufIdx--]);
return (NOERROR);
}
/* ------------------------------------------------------------------------ */
#include <fcntl.h>
#include <io.h>
int ScrReadWindow (char *Buffer, char *FileName)
/*
This function reads the 4000-byte screen image file specified by
'FileName' (may contain a full path), into the buffer pointed to by
'Buffer'.
*/
{
int FileHandle;
if ((FileHandle = open (FileName,O_RDONLY | O_BINARY)) == -1)
return (OPENERR);
if (read (FileHandle, Buffer, 4000) != 4000)
return (READERR);
if (close (FileHandle) == -1)
return (CLOSERR);
return (NOERROR);
}
#include <stdarg.h>
void PutStr(int Col, int Row, int Attr, char *fmt, ...)
{
va_list arg_ptr;
char t[100];
va_start(arg_ptr, fmt);
vsprintf(t, fmt, arg_ptr);
ScrPutS(t, Attr, Row, Col);
va_end(arg_ptr);
}
void Scroll(int x, int y, int xx, int yy, int direc, int attr)
{
union REGS r;
if (direc == 0) r.h.ah = 6;
else r.h.ah = 7;
r.h.al = 1;
r.h.ch = y;
r.h.cl = x;
r.h.dh = yy;
r.h.dl = xx;
r.h.bh = attr;
int86(0x10, &r, &r);
}
void ScrPutBox (int ULC, int ULR, int LRC, int LRR, int Style)
/*
This function displays a box at the specified coordinates on the screen.
'Style' may be from 0 to 3.
*/
{
register int i;
int Delta1, Delta2;
/* Store the box characters for each style */
static char ulc [] = {218,201,213,214};
static char urc [] = {191,187,184,183};
static char llc [] = {192,200,212,211};
static char lrc [] = {217,188,190,189};
static char hl [] = {196,205,205,196};
static char vl [] = {179,186,179,186};
int Vseg; /* Segment address for video memory */
char far *Video; /* Far pointer to video memory */
Delta1 = (LRC - ULC) * 2; /* Bytes between 2 vertical lines */
Delta2 = 160 - Delta1; /* Bytes between right vertical */
/* line and left vertical line of */
/* next row. */
if (*(char far *)0x00400049 == 7) /* Test video mode */
Vseg = 0xb000;
else
Vseg = 0xb800;
Video = MK_FP (Vseg, ULR*160+ULC*2);/* Initialize far pointer to */
/* upper left corner of box */
*Video = ulc [Style]; /* draw upper left corner */
Video += 2; /* Skip attribute byte ??? */
for (i=1; i<=LRC-ULC-1; ++i) { /* Draw top horizontal line */
*Video = hl [Style];
Video += 2;
}
*Video = urc [Style]; /* Draw upper right corner */
Video += Delta2;
for (i=1; i<=LRR-ULR-1; ++i) { /* Draw both vertical lines */
*Video = vl [Style]; /* Left vertical line */
Video += Delta1;
*Video = vl [Style]; /* Right vertical line */
Video += Delta2;
}
*Video = llc [Style]; /* Draw lower left corner */
Video += 2;
for (i=1; i<=LRC-ULC-1; ++i) { /* Draw bottom horiz line */
*Video = hl [Style];
Video +=2;
}
*Video = lrc [Style]; /* Draw lower right corner */
}
void StyleBox (int x, int y, int xx, int yy, int Attr)
{
register int i;
int Delta1, Delta2;
int Vseg; /* Segment address for video memory */
char far *Video; /* Far pointer to video memory */
Delta1 = (xx - x) * 2; /* Bytes between 2 vertical lines */
Delta2 = 160 - Delta1; /* Bytes between right vertical */
/* line and left vertical line of */
/* next row. */
if (*(char far *)0x00400049 == 7) /* Test video mode */
Vseg = 0xb000;
else
Vseg = 0xb800;
Video = MK_FP (Vseg, y*160+x*2); /* Initialize far pointer to */
/* upper left corner of box */
*Video = 218; /* draw upper left corner */
Video += 2; /* Skip attribute byte ??? */
for (i=1; i<=xx-x-1; ++i) { /* Draw top horizontal line */
*Video = 196;
Video += 2;
}
*Video = 183; /* Draw upper right corner */
Video += Delta2;
for (i=1; i<=yy-y-1; ++i) { /* Draw both vertical lines */
*Video = 179; /* Left vertical line */
Video += Delta1;
*Video = 186; /* Right vertical line */
Video += Delta2;
}
*Video = 212; /* Draw lower left corner */
Video += 2;
for (i=1; i<=xx-x-1; ++i) { /* Draw bottom horiz line */
*Video = 205;
Video +=2;
}
*Video = 188; /* Draw lower right corner */
/* Attributes */
SetAttrib(Attr, x, y, xx, y); /* Top */
SetAttrib(Attr, x, y, x, yy); /* Left side */
SetAttrib(Attr, xx, y, xx, yy); /* Right side */
SetAttrib(Attr, x, yy, xx, yy); /* Bottom */
}
void ScrClear (int StartCol, int StartRow, int StopCol, int StopRow)
{
_BH = 0x07; /* Use normal, white on black attribute */
_CH = StartRow;
_CL = StartCol;
_DH = StopRow;
_DL = StopCol;
_AX = 0x0600; /* BIOS scroll page up function */
geninterrupt (0x10);
}
void Cls(void) /* self explanetory */
{
ScrClear (0,0,80,25);
}
void HideCur(void)
{
ScrSetCur (0, 26, 0);
}
void RestCur(void)
{
ScrSetStyle(0x06, 0x07);
ScrSetCur (0, 0, 0);
}
void ShadowBox(int x, int y, int xx, int yy, int style, int attr)
{
ClrScrn(x,y,xx,yy, attr);
DrawBox(x,y,xx,yy, style, attr);
SetAttrib(0x08, x+2, yy+1, xx+2, yy+1);
SetAttrib(0x08, xx+1, y+1, xx+2, yy+1);
nosound();
}
void ClrScrn (int x, int y, int xx, int yy, int attr)
{
_BH = attr;
_CL = x;
_CH = y;
_DL = xx;
_DH = yy;
_AX = 0x0600; /* BIOS scroll page up function */
geninterrupt (0x10);
}
ScrGetS (char *Buffer, int Attr, int Col, int Row, int Length, int Mode)
/*
This function reads characters into 'Buffer', echoing the input starting
at 'Row' and 'Column', using video attribute 'Attr'. Characters are
read until an exit key (CR, Esc, or arrow) is encountered, or until the
number read is one less than the specified buffer size, 'Length'. If
the first key pressed is an exit key, the buffer is unaltered.
Otherwize, the buffer is initially filled with blanks and terminated
with a null; therefore, the resulting string will be blank-padded on the
right. The terminating exit key is not placed into the buffer. The
'Length' parameter should equal the 'sizeof' the receiving buffer.
The 'Mode' parameter can specify one or more of the following features
(constants defined in SCR.H):
NOFEAT: No 'Mode' feature specified.
AUTOEXIT: Exit field automatically when buffer is full.
UPPER: Convert all letters to uppercase.
DIR: Add '\' to ':' and no space fill on first char.
The function returns one of the following codes indicating the field
exit key pressed by the user:
-1 <Esc>
0 <CR>
1 <Left-Arrow>
2 <Right-Arrow>
3 <Up-Arrow>
4 <Down-Arrow>
5 Automatic exit (last character entered and AUTOEXIT selected).
*/
{
register int CurCol, i; /* current column/loop index */
int Vseg; /* segment of video memory */
int far *Video; /* far pointer to video memory */
int Key; /* stores input key value */
int FirstChar = 1; /* flag to indicate the first character */
char *ChPt; /* for filling buffer with blanks */
int far *IntFP; /* for filling buffer with blanks */
CurCol = Col; /* Initialize current column */
if (*(char far *)0x00400049 == 7)
Vseg = 0xb000;
else
Vseg = 0xb800;
Video = MK_FP (Vseg, Row*160+Col*2);
ScrSetStyle(0x06, 0x07);
ScrPutAttr(Attr, CurCol, Row, CurCol, Row);
if (Mode == DIR) {
CurCol += strlen(Buffer);
while (*Buffer)
*Video++ = (Attr << 8) | *Buffer++;
}
else
CurCol = Col;
ScrSetCur(CurCol,Row,0);
for (;;) /* Keyboard read loop */
switch (Key = KbdGetC ())
{
case 0x011b: /* Escape */
return (-1);
case 0x4b00: /* Left-Arrow */
return (1);
case 0x4d00: /* Right-Arrow */
return (2);
case 0x4800: /* Up-Arrow */
return (3);
case 0x5000: /* Down-Arrow */
return (4);
case 0x1c0d: /* Return */
return (0);
case 0x0e08: /* Backspace */
if (CurCol > Col) {
*--Video = (Attr << 8) | ' ';
*--Buffer = ' ';
ScrSetCur (--CurCol,Row, 0);
}
break;
default:
if (CurCol >= Col + Length - 1) /* Test end of buffer */
break;
if (Key&0x00ff == 0) /* Test for non-ASCII char */
break;
if (Mode & UPPER) /* Uppercase conversion */
Key = toupper (Key&0x00ff);
else
Key &= 0x00ff; /* Remove extended code */
/* Place key in video memory & buffer */
*Video++ = (Attr << 8) | Key;
*Buffer++ = Key;
ScrSetCur (++CurCol, Row,0); /* Update cursor position */
if (Mode == DIR) { /* Add '\' to ':' */
Key = toupper (Key&0x00ff);
if (Key == 0x003a) {
*Video++ = (Attr << 8) | 0x005c;
*Buffer++ = 0x005c;
ScrSetCur (++CurCol, Row,0);
}
*Buffer = '\0';
}
if (FirstChar) /* Blank-fill buffer on first character */
{
FirstChar = 0;
ChPt = Buffer;
IntFP = Video;
for (i=1; i<=Length-2; ++i) {
*ChPt++ = ' ';
*IntFP++ = (Attr << 8) | ' ';
}
*ChPt = '\0';
}
/* Test for autoexit */
if ((CurCol >= Col + Length - 1) && (Mode & AUTOEXIT))
return (5); /* Code for autoexit */
break;
}
}
void ScrPutAttr( int Attr, int StartCol, int StartRow,
int StopCol, int StopRow )
{
register int Row, Col;
int Vseg, CharPerRow, Delta;
char far *Video; /* Far pointer to video memory. */
if (*(char far *)0x00400049 == 7) /* Test video mode */
Vseg = 0xb000;
else
Vseg = 0xb800;
/* Initialize pointer to first attribute in video memory */
Video = MK_FP (Vseg,(StartRow*160+StartCol*2)+1);
/* Calculate characters per row */
CharPerRow = StopCol - StartCol + 1;
/* Calculate increment value between rows */
Delta = 160 - (StopCol - StartCol + 1) * 2;
for( Row=1 ; Row<=StopRow-StartRow+1 ; ++Row ){
for( Col=1 ; Col<=CharPerRow; ++Col ){ /* Display a row */
*Video = Attr; /* Write the attribute */
Video += 2; /* Increment to next attribute */
}
Video += Delta; /* Increment to next row */
}
}